function PDGeneralState(pdObjs) {
    this.uID = -1;
//    this.blendName = "";
    this.blendType = 0;
    this.strokeAlpha = 0.0;
    this.fillAlpha = 0.0;
    this.ctm = null;
    this.m_softMask = null; //PDSoftMask object
    //this.m_nMatrixID = -1;  
    this.m_pdObjs = pdObjs;

    this.SetCTM = function (matrix) {
        var mt = new PDMatrix();
        mt.Set(matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]);
        this.ctm = mt;
    };
    this.GetCTM = function () {
        return this.ctm;
    };

    this.ParseFromBin = function (rd) {
        this.uID = rd.readUint16();
        //this.m_nMatrixID = rd.readUint16();
        this.ctm = this.m_pdObjs.GetMatrixByID(rd.readUint16());
        this.blendType = rd.readByte();
        this.fillAlpha = rd.readFloat32();
        this.strokeAlpha = rd.readFloat32();
        
        var bHasSoftInfo = rd.readByte();
        if (1 == bHasSoftInfo) {
            this.m_softMask = new PDSoftMask();
            this.m_softMask.m_genState = this;
            this.m_softMask.ParseFromBin(rd);
        }
        

    };


    PDGeneralState.prototype.FromJson = function (jsonData) {
        var state = new PDGeneralState();
        state.ParseJson(jsonData);
        return state;
    };
    
   this.ParseJson = function (arrayData) {
        //var this = this;
        this.uID = arrayData[0];
    //    this.blendName = arrayData[2];
        this.blendType = arrayData[3];
        this.strokeAlpha = arrayData[4];
        this.fillAlpha = arrayData[5];
        this.SetCTM(arrayData[1]);
   };
}

function PDGraphState() {
    this.uID = -1;
    this.nCapStyle = 0;
    this.nDashCount = 0;
    this.lsDash = []; //dash array
    this.nDashPhase = 0;
    this.fJoinMiterLimit = 0;
    this.joinStyle = 0;
    this.fLineWidth = 0;

    this.ParseFromBin = function (rd) {

        this.uID = rd.readUint16();
        this.nCapStyle = rd.readByte();
        this.nDashCount = rd.readInt32();
        for (var i = 0; i < this.nDashCount; i++) {
            this.lsDash[i] = rd.readFloat32();
        }

        this.nDashPhase = rd.readFloat32();
        this.joinStyle = rd.readByte();
        this.fJoinMiterLimit = rd.readFloat32();
        this.fLineWidth = rd.readFloat32();
    };
    
    this.ParseJson = function (arrayData) {
        //var self = this;
        this.uID = arrayData[0];
        this.nCapStyle = parseFloat(arrayData[2]);
        //self.nDashCount = u; 
        this.lsDash = [parseFloat(arrayData[3][0]),parseFloat(arrayData[3][1])];
        this.nDashPhase = parseFloat(arrayData[3][2]);
        this.joinStyle = arrayData[4];
        this.fJoinMiterLimit = parseFloat(arrayData[5]);
        this.fLineWidth = parseFloat(arrayData[1]);
    };
    
    PDGraphState.prototype.FromJson = function (jsonData) {
        var state = new PDGraphState();
        state.ParseJson(jsonData);
        return state;
    };
}

function PDColorState(pdObjs) {
    this.uID = -1;
    this.fillRGB = 0;
    this.strokeRGB = 0;
    this.strokeShadingPattern = null;
    this.strokeTilingPattern = null;
    this.fillShadingPattern = null;
    this.fillTilingPattern = null;
    this.m_pdObjs = pdObjs;
    this.ParseFromBin = function (rd) {
        this.uID = rd.readUint16();
        this.fillRGB = rd.readUint32();
        this.strokeRGB = rd.readUint32();
        var flag = rd.readByte();
        if (flag & 0x01) {
            //   this.bFillPattern = true;
            var sh = new ShadingPattern();
            sh.ParseFromBin(rd);
            this.fillShadingPattern = sh;
        }
        else if (flag & 0x04) {
            var tiling = new TillingPattern(this.m_pdObjs);
            tiling.ParseFromBin(rd);
            this.fillTilingPattern = tiling;
        }
        if (flag & 0x02) {
            var sh = new ShadingPattern();
            sh.ParseFromBin(rd);
            this.strokeShadingPattern = sh;
        }
        else if (flag & 0x08) {
            var tiling = new TillingPattern(this.m_pdObjs);
            tiling.ParseFromBin(rd);
            this.strokeTilingPattern = tiling;
        }

    };

    this.ParseJson = function (arrayData) {
        this.uID = arrayData[0];
        this.fillRGB = arrayData[1];
        this.strokeRGB = arrayData[2];
        if (arrayData[3] != null) this.strokeShadingPattern = ShadingPattern.prototype.FromJson(arrayData[3]);
        if (arrayData[4] != null) this.strokeTilingPattern = TillingPattern.prototype.FromJson(arrayData[4]);
        if (arrayData[5] != null) this.fillShadingPattern = ShadingPattern.prototype.FromJson(arrayData[5]);
        if (arrayData[6] != null) this.fillTilingPattern = TillingPattern.prototype.FromJson(arrayData[6]);
    };
    
    PDColorState.prototype.FromJson = function (jsonData) {
        var state = new PDColorState();
        state.ParseJson(jsonData);
        return state;
    };
}

function PDTextState() {
    this.uID = -1;
    this.nFontID = -1;
    this.fontSize = 1.0;
 //   this.charSpace = 1.0;
 //   this.wordSpace = 1.0;
 //   this.textCTM = null;
    this.nTextMode = 0;
    //   this.strokeCTM = null;

    this.ParseFromBin = function (rd) {

        this.uID = rd.readUint16();
        this.nFontID = rd.readUint16();
        this.fontSize = rd.readFloat32();
        this.nTextMode = rd.readByte();
    };

    this.SetTextCTM = function (matrix) {
        var mt = new PDMatrix();
        //mt.Set(matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]);
        mt.Set(parseFloat(matrix[0]), parseFloat(matrix[1]), parseFloat(matrix[2]), parseFloat(matrix[3]), 0, 0);
        this.textCTM = mt;
    };
    /*
    this.GetTextCTM = function () {
        return this.textCTM;
    };

    this.SetStrokeCTM = function (matrix) {
        var mt = new PDMatrix();
        //mt.Set(matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]);
        mt.Set(parseFloat(matrix[0]), parseFloat(matrix[1]), parseFloat(matrix[2]), parseFloat(matrix[3]), 0, 0);
        this.strokeCTM = mt;
    };
    this.GetStrokeCTM = function () {
        return this.strokeCTM;
    };
    
    this.ParseJson = function (arrayData) {
        //var this = this;
        this.uID = arrayData[0];
        this.nFontID = arrayData[1];
        this.fontSize = parseFloat(arrayData[2]);
        this.charSpace = parseFloat(arrayData[3]);
        this.wordSpace = parseFloat(arrayData[4]);
        this.SetTextCTM(stringArr2NumArr(arrayData[6]));
        this.nTextMode = arrayData[5];
        this.SetStrokeCTM(stringArr2NumArr(arrayData[7]));
    };
    
    PDTextState.prototype.FromJson = function (jsonData) {
        var state = new PDTextState();
        state.ParseJson(jsonData);
        return state;
    };
    */
}

function PDClipText() {
    this.mtGen = null;
	this.m_fFillAlpha = 1.0;
	this.m_fStrokeAlpha = 1.0;
	this.m_LineCap = 0;
	this.m_LineJoin = 0;
	this.m_MiterLimit = 1;
	this.m_LineWidth = 1.0; 
	this.m_FillRGB = 0xffffffff;
	this.m_StrokeRGB = 0xffffffff;
	this.m_nFontID = -1;
	this.m_fFontsize = 1.0;
	this.m_nTextMode = 0;

	this.matrix = null;
	this.m_BBox = [];
	this.m_Org = [];
	this.m_bVert = false;
	this.m_nContentLen = 0;
	this.m_content = "";
	this.m_nChar = 0;
	this.m_charPosArray = [];
	this.GetContent = function () {
	    return this.m_content;
	};
	this.ParseFromBin = function (rd) {
	    var a = rd.readFloat32();
	    var b = rd.readFloat32();
	    var c = rd.readFloat32();
	    var d = rd.readFloat32();
	    var e = rd.readFloat32();
	    var f = rd.readFloat32();
	    this.mtGen = new PDMatrix();
	    this.mtGen.Set(a, b, c, d, e, f);

	    this.m_fFillAlpha = rd.readFloat32();
	    this.m_fStrokeAlpha = rd.readFloat32();
	    this.m_LineCap = rd.readByte();
	    this.m_LineJoin = rd.readByte();
	    this.m_MiterLimit = rd.readFloat32();
	    this.m_LineWidth = rd.readFloat32();
	    this.m_FillRGB = rd.readUint32();
	    this.m_StrokeRGB = rd.readUint32();
	    this.m_nFontID = rd.readUint16();
	    this.m_fFontsize = rd.readFloat32();
	    this.m_nTextMode = rd.readByte();

	    a = b = c = d = e = f = 0;
	    a = rd.readFloat32();
	    b = rd.readFloat32();
	    c = rd.readFloat32();
	    d = rd.readFloat32();
	    e = rd.readFloat32();
	    f = rd.readFloat32();
	    this.matrix = new PDMatrix();
	    this.matrix.Set(a, b, c, d, e, f);

	    var l = rd.readFloat32();
	    var t = rd.readFloat32();
	    var r = rd.readFloat32();
	    var bottom = rd.readFloat32();
	    this.m_BBox = [l, t, r, bottom];
	    var x = rd.readFloat32();
	    var y = rd.readFloat32();
	    this.m_Org = [x, y];
	    this.m_bVert = rd.readByte();
	    var nCon = rd.readUint32();
	    this.m_content = rd.readString(nCon);
	    var nChar = rd.readUint32();
	    for (var i = 0; i < nChar; i++) {
	        var w = rd.readFloat32();
	        this.m_charPosArray[i] = w;
	    }


	};
}

function PDClipPathState(pdPage) {
	this.uID = -1;
	//[[[ptX,ptY,ptFlag],[ptX,ptY,ptFlag],...],[[ptX,ptY,ptFlag],[ptX,ptY,ptFlag],...],...]
	this.clipPath = [];
	this.clipPathFlag  = [];
	// text object for clip
	this.textObjs = [];
	this.m_pdPage = pdPage;

	this.ParseFromBin = function (rd) {
	    this.uID = rd.readUint16();
	    var nPath = rd.readUint16();
	    for (var i = 0; i < nPath; i++) {
	        var path = [];
	        var nPoint = rd.readInt32();
	        for (var j = 0; j < nPoint; j++) {
	            var point = [];
	            flag = rd.readByte();
	            point[0] = rd.readFloat32();
	            point[1] = rd.readFloat32();
	            point[2] = flag;

	            path.push(point);
	        }
	        var f = rd.readByte();
	        this.clipPathFlag.push(f);
	        this.clipPath[i] = path;
	    }
	    /*
	    for (var n = 0; n < nPath; n++) {
	    var flag = rd.readByte();
	    this.clipPathFlag.push(flag);
	    }
	    */
	    var nText = rd.readUint16();
	    for (var k = 0; k < nText; k++) {
	        var t = new PDClipText();
	        t.ParseFromBin(rd);
	        this.textObjs[k] = t;
	    }
	};
}

PDClipPathState.prototype.CountTextClipObjs = function() {
	return this.textObjs.length;
};

PDClipPathState.prototype.GetTextClipObjByIndex = function (i) {
	if (i < 0 || i >= this.textObjs.length) {
		return null;
	}
	return this.textObjs[i];
};

PDClipPathState.prototype.Equal = function (other) {
    return this.uID == other.uID;
};

PDClipPathState.prototype.ParseJson = function (arrayData) {
    //var self = this;
    var tempObj = null;
    this.uID = arrayData[0];

    if (Object.prototype.toString.call(arrayData[1]) === '[object Array]') {
        for (var i = 0, tempItemi = null; i < arrayData[1].length; i++) {
            tempItemi = arrayData[1][i];
            this.AddClipPath(tempItemi);
        }
    }


    if (Object.prototype.toString.call(arrayData[2]) === '[object Array]') {
    for (var j = 0, tempItemj = null; j < arrayData[2].length; j++) {
		tempItemj = arrayData[2][j];
		this.clipPathFlag.push(tempItemj);
	}
    }
    
    if (Object.prototype.toString.call(arrayData[3]) === '[object Array]')
    {
        for (var k = 0, tempItemk = null; k < arrayData[3].length; k++) {
        tempItemk = arrayData[3][k];
		tempObj = new TextObj();
		tempObj.ParseJson(tempItemk);
		this.textObjs.push(tempObj);
	}
    }
    
};

PDClipPathState.prototype.AddClipPath = function (clipPathData) {
	var item = null;
	var clipDataArr = [];
    if(Object.prototype.toString.call(clipPathData) === '[object Array]')
    {
    for (var i = 0, len = clipPathData.length; i < len; i++) {
		item = clipPathData[i];
		clipDataArr.push([parseFloat(item[1]), parseFloat(item[2]), item[0]]);
	}
	this.clipPath.push(clipDataArr);
    }
	
};





